<!--
author: 何其沆(pooky)
desc: 添加或编辑contract
date: 2021-12-08
-->
<template>
  <div class="add-or-edit-contract">
    <e-container class="container" :loading="loading">
      <e-title :title="route.params.action === 'add' ? 'Add Contract' : 'Edit Contract'" />
      <div class="line"></div>
      <div class="form-container">
        <a-form ref="formRef" layout="vertical" :model="state" :rules="rules">
          <a-row :gutter="gutter">
            <a-col :span="12">
              <a-form-item ref="type" label="Type" name="type">
                <a-select
                  v-model:value="state.type"
                  :disabled="route.params.action === 'edit'"
                  show-search
                  option-filter-prop="label"
                  option-label-prop="label"
                  :get-popup-container="triggerNode => triggerNode.parentNode"
                >
                  <a-select-option v-for="item in contractTypes" :key="item.value" :label="item.text">
                    {{ item.text }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
            <a-col v-if="!dontNeedContractNumber" :span="12">
              <a-form-item ref="contractNumber" label="Contract Number" name="contractNumber">
                <a-select
                  v-model:value="state.contractNumber"
                  show-search
                  allow-clear
                  option-filter-prop="label"
                  option-label-prop="label"
                  placeholder="Please select"
                >
                  <a-select-option
                    v-for="item in contractNumberList"
                    :key="item.contractNumber"
                    :label="item.contractNumber"
                  >
                    {{ item.contractNumber }}
                  </a-select-option>
                </a-select>
                <!--
                <a-button
                  type="primary"
                  ghost
                  style="width: 96px; margin-left: 4px"
                  @click="showGenerateContractNumber = true"
                >
                  <a-space>
                    <e-icon type="add" font-size="16px" />
                    Create
                  </a-space>
                </a-button>
                -->
              </a-form-item>
            </a-col>
          </a-row>
          <a-row v-if="!dontNeedContractNumber" :gutter="gutter">
            <a-col :span="12">
              <a-form-item ref="startDate" label="Start Date" name="startDate">
                <a-date-picker
                  v-model:value="state.startDate"
                  :disabled-date="startDisabledDate"
                  :get-popup-container="triggerNode => triggerNode.parentNode"
                ></a-date-picker>
              </a-form-item>
            </a-col>
            <a-col :span="12">
              <a-form-item ref="endDate" label="End Date" name="endDate">
                <a-date-picker
                  v-model:value="state.endDate"
                  :disabled-date="endDisabledDate"
                  :get-popup-container="triggerNode => triggerNode.parentNode"
                ></a-date-picker>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row v-if="dontNeedContractNumber" :gutter="gutter">
            <a-col :span="24">
              <a-form-item label="Date to follow up" name="planDate">
                <a-date-picker
                  v-model:value="state.planDate"
                  value-format="YYYY-MM-DD"
                  :disabled-date="disabledDate"
                  :get-popup-container="triggerNode => triggerNode.parentNode"
                ></a-date-picker>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row v-if="!dontNeedContractNumber" :gutter="gutter">
            <a-col :span="12">
              <div class="it-item">
                <div class="title">Automatic contract renewal on end date</div>
                <div class="select-area">
                  <a-radio-group v-model:value="state.radioValue" style="display: flex; width: 100%">
                    <div class="radio-group" @click="state.radioValue = false">
                      <a-radio :value="false">No</a-radio>
                    </div>
                    <div class="radio-group" @click="state.radioValue = true">
                      <a-radio :value="true">Yes</a-radio>
                    </div>
                  </a-radio-group>
                </div>
              </div>
            </a-col>
          </a-row>
          <a-row :gutter="gutter">
            <a-col :span="24">
              <a-form-item
                ref="signedCompany"
                label="Signed Company"
                name="signedCompany"
                :style="{ 'margin-top': !dontNeedContractNumber ? '24px' : 0 }"
              >
                <a-select
                  v-model:value="state.signedCompany"
                  show-search
                  :disabled="!dontNeedContractNumber"
                  option-filter-prop="label"
                  :get-popup-container="triggerNode => triggerNode.parentNode"
                >
                  <a-select-option v-for="item in companies" :key="item.value" :label="item.text + item.nameEN">
                    <a-space>
                      {{ item.text }}
                      <span v-if="item.text !== item.nameEN" style="color: #bfbfbf">
                        {{ item.nameEN }}
                      </span>
                    </a-space>
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
          </a-row>
          <a-row :gutter="gutter">
            <a-col :span="24">
              <a-form-item ref="note" label="Note" name="note">
                <a-textarea v-model:value="state.note" autocomplete="off" />
              </a-form-item>
            </a-col>
          </a-row>
          <div class="attachment">
            <input v-show="false" ref="uploadInput" type="file" @change="uploadFileChange" />
            <a-form-item name="fileName" label="Attachment">
              <a-input v-model:value="fileName" readonly>
                <template #addonAfter>
                  <span style="cursor: pointer" @click="uploadInput.click()">
                    <e-icon type="upload" color="#a9b5c9" />
                    <span style="font-size: 12px; color: #a9b5c9; margin-left: 6px">Upload</span>
                  </span>
                </template>
              </a-input>
            </a-form-item>
          </div>
        </a-form>
        <div class="line"></div>
        <div class="bottom">
          <a-button style="margin-right: 24px" @click="cancelAdd">Cancel</a-button>
          <a-button
            v-permission="route.params.action === 'add' ? 'Contract:Add' : 'Contract:Edit'"
            type="primary"
            @click="handleSave"
            >Save</a-button
          >
        </div>
      </div>
    </e-container>
    <generate-contract-number
      v-model:show="showGenerateContractNumber"
      :client-id="route.params.id"
      auto-inject
      @inject="handleInject"
    />
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, watch, inject } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from 'vuex'
import dayjs from 'dayjs'
import Contract from '@/api/client/contract.js'
import TargetClient from '@/api/targetClient.js'
import { SAVED_SUCCESSFULLY, UPLOAD_FAILED, CONFIRM_BACK_TO_LIST } from '@/constants/message.js'
import EContainer from '@/components/EContainer.vue'
import ETitle from '@/components/ETitle.vue'
import EIcon from '@/components/EIcon.vue'
import GenerateContractNumber from './generateContractNumber.vue'
const { Modal, message } = inject('Feedback')
const emits = defineEmits(['update'])
const route = useRoute()
const router = useRouter()
const store = useStore()
const loading = ref(true)
const gutter = [120, 16]
const dict = ref(computed(() => store.state.dict))
const contractTypes = ref([])
const companies = ref([])
const formRef = ref()
const flag = ref()
const fileName = ref()
const items = ref()
const state = reactive({
  // contractName: '',
  contractNumber: '',
  type: '',
  startDate: null,
  endDate: null,
  planDate: null,
  radioValue: false,
  signedCompany: '',
  note: '',
  attachmentAddr: '',
  attachmentName: '',
  attachmentFileSize: 0
})
const uploadInput = ref(null)
// 创建合同号弹窗
const showGenerateContractNumber = ref(false)
// 创建合同号后自动回填
const handleInject = number => {
  getContractNumberList().then(() => {
    state.contractNumber = number
  })
}
// 可用合同号
const contractNumberList = ref([])
// 临时合作申请最多可选择90天后
const disabledDate = current => {
  return current > dayjs().add(2160, 'h') || current < dayjs().startOf('day')
}
// 根据选择的合同号自动选择签约公司
watch(
  () => state.contractNumber,
  value => {
    if (!dontNeedContractNumber.value) {
      const target = contractNumberList.value.find(item => item.contractNumber === value)
      state.signedCompany = target?.contractNumber ? target.branch : ''
    }
  }
)
// 不需要填写合同号的类型
const dontNeedContractNumber = computed(() => state.type === 5)
// 校验规则
const rules = {
  contractNumber: [
    {
      required: true,
      message: 'Please input Contract Number.'
    }
  ],
  type: [
    {
      required: true,
      message: 'Please select Type.'
    }
  ],
  startDate: [
    {
      required: true,
      message: 'Please select Start Date.'
    }
  ],
  endDate: [
    {
      required: true,
      message: 'Please select Date to follow up.'
    }
  ],
  planDate: [
    {
      required: true,
      message: 'Please select End Date.'
    }
  ],
  signedCompany: [
    {
      required: true,
      message: 'Please select Signed Company.'
    }
  ],
  note: [
    {
      max: 200,
      message: 'Only 200 characters can be entered.'
    }
  ],
  fileName: [
    {
      required: true,
      validator: () => {
        return fileName.value ? Promise.resolve() : Promise.reject(new Error())
      },
      message: 'Please upload attachment.'
    }
  ]
}
// 获取可用合同号
const getContractNumberList = () =>
  new Promise((resolve, reject) => {
    Contract.getContractNumberList(route.params.id)
      .then(({ data }) => {
        contractNumberList.value = data
        resolve()
      })
      .catch(e => reject(e))
  })
getContractNumberList()
store.dispatch('dict/getClientContractTypes').then(() => {
  if (dict.value.clientContractTypes.length > 0) {
    contractTypes.value = [...contractTypes.value, ...dict.value.clientContractTypes]
  }
})
store.dispatch('dict/getEciCompanies').then(() => {
  if (dict.value.eciCompanies.length > 0) {
    companies.value = [...companies.value, ...dict.value.eciCompanies]
  }
})
/**
 * 取消添加
 */
const cancelAdd = () => {
  Modal.confirm({
    content: CONFIRM_BACK_TO_LIST,
    okButtonProps: { danger: true },
    onOk: () => {
      router.push({ name: 'Client Contract' })
      emits('update')
    }
  })
}
/**
 * 保存
 */
const handleSave = () => {
  /**
  不需要合同号时覆盖检查合同号存在的方法
   */
  const isExistFunction = data => {
    return new Promise(resolve => {
      if (dontNeedContractNumber.value) {
        resolve({ code: 2000, data: false })
      } else {
        Contract.contractNumberIsExits({
          contractID: data.contractID,
          contractNumber: data.contractNumber
        }).then(res => {
          resolve(res)
        })
      }
    })
  }
  formRef.value.validate().then(() => {
    const clientOrgID = route.params.id
    const startDate = dayjs(state.startDate).format('YYYY-MM-DD')
    const endDate = dayjs(state.endDate).format('YYYY-MM-DD')
    const planDate = dayjs(state.planDate).format('YYYY-MM-DD')
    if (route.params.action === 'edit') {
      isExistFunction({
        contractID: items.value.id,
        contractNumber: state.contractNumber
      }).then(res => {
        if (res.code === 2000) {
          if (!res.data) {
            let attachFile = 0
            if (flag.value === 1) {
              attachFile = 0
            } else {
              attachFile = items.value.attachFile
            }
            Contract.updateContractInfo({
              id: items.value.id,
              contractNumber: dontNeedContractNumber.value ? undefined : state.contractNumber.trim(),
              contractType: state.type,
              startDate: dontNeedContractNumber.value ? undefined : startDate,
              endDate: dontNeedContractNumber.value ? undefined : endDate,
              followUp: !dontNeedContractNumber.value ? undefined : planDate,
              isRenewal: dontNeedContractNumber.value ? undefined : state.radioValue,
              signedCompany: state.signedCompany,
              description: state.note.trim(),
              attachmentAddr: state.attachmentAddr,
              attachmentName: state.attachmentName,
              attachmentFileSize: 0,
              attachFile: attachFile
            }).then(res => {
              if (res.code === 2000) {
                message.success(SAVED_SUCCESSFULLY)
                router.push({ name: 'Client Contract' })
                emits('update')
              }
            })
          } else {
            message.error('The Contract Number cannot be applied for repeatedly!')
          }
        }
      })
    } else {
      isExistFunction({
        contractID: 0,
        contractNumber: state.contractNumber
      }).then(res => {
        if (res.code === 2000) {
          if (!res.data) {
            Contract.createContractInfo({
              clientOrgID,
              contractNumber: dontNeedContractNumber.value ? undefined : state.contractNumber.trim(),
              contractType: state.type,
              startDate: dontNeedContractNumber.value ? undefined : startDate,
              endDate: dontNeedContractNumber.value ? undefined : endDate,
              followUp: !dontNeedContractNumber.value ? undefined : planDate,
              isRenewal: dontNeedContractNumber.value ? undefined : state.radioValue,
              signedCompany: state.signedCompany,
              description: state.note.trim(),
              attachmentAddr: state.attachmentAddr,
              attachmentName: state.attachmentName,
              attachmentFileSize: 0
            }).then(res => {
              if (res.code === 2000) {
                message.success(SAVED_SUCCESSFULLY)
                router.push({ name: 'Client Contract' })
                emits('update')
                formRef.value.resetFields()
                state.radioValue = ''
                fileName.value = ''
              }
            })
          } else {
            message.error('The Contract Number cannot be applied for repeatedly!')
          }
        }
      })
    }
  })
}
/**
 * 上传附件
 * @param event
 */
const uploadFileChange = event => {
  if (fileName.value) {
    flag.value = 1
  }
  if (event.target.files.length > 0) {
    TargetClient.uploadFiles(event.target.files)
      .then(res => {
        if (Array.isArray(res) && res.length > 0 && res[0] instanceof Eci.IO.File) {
          fileName.value = event.target.files.length > 0 ? event.target.files[0].name : ''
          state.attachmentAddr = res[0].Path
          state.attachmentFileSize = res[0].SourceBaseFileSize
          state.attachmentName = fileName.value
          formRef.value.clearValidate('fileName')
        } else {
          fileName.value = ''
          message.error(UPLOAD_FAILED)
        }
      })
      .catch(() => {
        fileName.value = ''
        uploadInput.value.value = null
        message.error(UPLOAD_FAILED)
      })
  }
}
/**
 * 开始时间禁用
 * @param current
 */
const startDisabledDate = current => {
  return current > dayjs(state.endDate).endOf('day')
}
/**
 * 结束时间禁用
 * @param current
 */
const endDisabledDate = current => {
  return current < dayjs(state.startDate).endOf('day')
}
/**
 * 初始化
 */
onMounted(() => {
  if (route.params.action === 'edit') {
    document.title = 'Edit Contract'
    const id = route.params.cid
    Contract.getClientContractInfo({
      contractID: id
    })
      .then(res => {
        if (res.code === 2000) {
          items.value = res.data
          state.contractNumber = res.data.contractNumber
          state.type = res.data.contractType
          state.startDate = dayjs(res.data.startDate)
          state.endDate = dayjs(res.data.endDate)
          state.planDate = dayjs(res.data.followUp)
          state.radioValue = res.data.isRenewal
          state.signedCompany = res.data.signedCompany
          state.note = res.data.description
          state.attachmentAddr = res.data.attachmentAddr
          state.attachmentName = res.data.attachmentName
          fileName.value = res.data.attachmentName
        }
      })
      .finally(() => {
        loading.value = false
      })
  } else {
    loading.value = false
    document.title = 'Add Contract'
  }
})
</script>

<style scoped lang="less">
.container {
  padding: 24px;
  .line {
    width: 100%;
    height: 1px;
    background-color: @lighter-gray;
    margin-top: 28px;
  }
  .form-container {
    width: 52.5vw;
    margin: 24px auto 0;
    .contract-name {
      width: 100%;
    }
    :deep(.ant-picker) {
      width: 100%;
    }
    .select-area {
      width: 100%;
      height: 32px;
      border: 1px solid @border-color;
      display: flex;
      border-radius: 2px;
      .radio-group {
        flex: 1;
        display: flex;
        padding-left: 12px;
        cursor: pointer;
        &:first-child {
          border-right: 1px solid @border-color;
        }
      }
    }
    .note {
      width: 100%;
      :deep(textarea.ant-input) {
        min-height: 80px;
      }
    }
    .attachment {
      width: 100%;
      margin-top: 16px;
    }
    .title {
      color: @deep-gray;
      font-size: 14px;
      margin-bottom: 8px;
    }
  }
  .bottom {
    display: flex;
    justify-content: center;
    padding: 30px 0 6px 0;
  }
  :deep(.ant-input),
  :deep(.ant-select-selector),
  :deep(.ant-picker) {
    border-color: @border-color;
  }
  :deep(.ant-form-item-has-error .ant-input),
  :deep(.ant-form-item-has-error .ant-input-affix-wrapper),
  :deep(.ant-form-item-has-error .ant-input:hover),
  :deep(.ant-form-item-has-error .ant-input-affix-wrapper:hover),
  :deep(.ant-form-item-has-error .ant-input-number),
  :deep(.ant-form-item-has-error .ant-picker) {
    border-color: #fc4b3b !important;
  }
}
</style>
<route lang="yaml">
name: Add Contract
path: '/client/:id/contract/:action/:cid'
meta:
  title: Add Contract
  permission: Contract
</route>
